<?php
declare (strict_types=1);

namespace app\common\logic;

use app\common\model\RouteMenuModel;
use app\common\validate\RouteMenuValidate;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\exception\ValidateException;
use utils\PHPTree;

/**=========================================
 * Copyright © 2023-2024, WICMS.CN. All Rights Reserved
 * Project Name: WiCMS
 * Description: 路由菜单逻辑层
 * Author: jason
 * Email: 52527998@QQ.COM
 * Date: 2024/11/4
 * Time: 16:51
 * File: app\common\Logic\RouteMenuLogic.php
 * =========================================
 */
class RouteMenuLogic extends BaseLogic
{

    public function _initialize(): void
    {
        parent::_initialize();
    }

    /**
     * 获取路由菜单列表
     *
     * @return array|string
     */
    public static function getRouteList(): array|string
    {
        try {
            $condition  = [
                ['menu_type', '=', 'menu'],
                ['status', '=', 1]
            ];
            $list       = RouteMenuModel::getList($condition);
            $formatMenu = self::formatData($list);
            return PHPTree::makeTree($formatMenu);
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 获取导航菜单列表数据
     *
     * @param array $condition 查询条件
     * @param bool  $is_tree
     *
     * @return array|string
     */
    public static function getList(array $condition = ['menu_type', '=', 'menu'], bool $is_tree = true): array|string
    {
        try {
            $list = RouteMenuModel::getList($condition);
            if ($is_tree) {
                return PHPTree::makeTree($list);
            }
            return $list;
        } catch (DataNotFoundException|ModelNotFoundException|DbException $e) {
            return $e->getMessage();
        }
    }

    /**
     * 格式化菜单数据
     *
     * @param array $menuList
     *
     * @return array
     */
    private static function formatData(array $menuList = []): array
    {
        $output = [];
        foreach ($menuList as $item) {
            $menu = [
                'id'   => $item['id'],
                'pid'  => $item['pid'],
                'path' => $item['route_path'],
                'name' => ucfirst($item['route_name']),
                'meta' => [
                    'title'      => $item['menu_name'],
                    'icon'       => $item['icon'],
                    'showLink'   => true,
                    'rank'       => $item['rank'],
                    'showParent' => true,
                    'roles'      => $item['roles'],
                    'auths'      => !empty($item['permission_code']) ? explode(',', $item['permission_code']) : ["*:*:*"],
                ],
            ];
            if (!empty($item['component_path'])) {
                $menu['component'] = $item['component_path'];
            }
            if (!empty($item['redirect_url'])) {
                $menu['redirect'] = $item['redirect_url'];
            }
            if (!empty($item['transition_name'])) {
                $menu['meta']['transition'] = [
                    'name'            => $item['transition_name'],
                    'enterTransition' => $item['enter_transition'],
                    'leaveTransition' => $item['leave_transition']
                ];
            }
            if (!empty($item['is_keep_alive'])) {
                $menu['meta']['keepAlive'] = $item['is_keep_alive'] == 1;
            }
            if (!empty($item['is_iframe']) && !empty($item['redirect_url'])) {
                $menu['meta']['frameSrc']     = $item['redirect_url'];
                $menu['meta']['frameLoading'] = $item['frame_loading'] == 1;
            }
            if (!empty($item['is_hide'])) {
                $menu['meta']['hiddenTag'] = $item['is_hide'] == 1;
            }
            $output[] = $menu;
        }
        return $output;
    }

    /**
     * @param array $data
     *
     * @return bool|string
     */
    public static function saveData(array $data): bool|string
    {
        $data['redirect_url'] = $data['menu_type'] == 'iframe' ? $data['frame_src'] : $data['redirect_url'];
        $data['is_link']      = $data['menu_type'] == 'link' ? 1 : 0;
        $data['is_iframe']    = $data['menu_type'] == 'iframe' ? 1 : 0;
        $menuData             = $data;
        if (empty($data['id'])) {
            $scene = 'add';
        } else {
            $scene = 'edit';
        }
        try {
            validate(RouteMenuValidate::class)
                ->scene($scene)
                ->check($menuData);
            $model = new RouteMenuModel();
            if ($scene == 'add') {
                $menu_id = $model->insertGetId($menuData);
            } else {
                $menu_id = $data['id'];
                $model->update($menuData, ['id' => $menu_id]);
            }
            // 更新菜单树
            $menuTree = $model->where('id', $menuData['pid'])->value('menu_tree') . ',' . $menu_id;
            RouteMenuModel::update(['menu_tree' => $menuTree], ['id' => $menu_id]);
            return true;
        } catch (ValidateException $e) {
            return $e->getError();
        }
    }

    public static function deleteData(array $data)
    {

    }

    public static function getRouteListForRole(): array
    {
        $field     = ['id', 'pid', 'menu_type', 'menu_name'];
        $condition = [
//            ['status', '=', 1]
        ];
        $list      = (new RouteMenuModel)->where($condition)->field($field)->order('rank', 'asc')->select();
        return $list->toArray();
    }

}